In computer systems, electronic chips and other components are connected with one another by buses. A variety of components can be connected to the bus, providing intercommunication between all of the devices that are connected to the bus. One type of bus which has gained wide industry acceptance is the industry standard architecture (ISA) bus. The ISA bus has twenty-four (24) memory address lines which therefore provides support for up to sixteen (16) megabytes of memory. The wide acceptance of the ISA bus has resulted in a very large percentage of devices being designed for use on the ISA bus. However, high input devices commonly used in computer systems require faster buses. A solution to the general problem of sending and receiving data from the processor to any high input device is a local bus. Unlike the ISA bus, which operates relatively slowly with limited bandwidth, a local bus communicates at system speed and carries data in 32-bit blocks. Local bus machines remove from the main system bus those interfaces that need quick response, such as memory, display, and disk drives. One such local bus that has gained wide acceptance in the industry is the peripheral component interconnect (PCI) bus. The PCI bus can be a 32 or 64-bit pathway for high-speed data transfer. Essentially, the PCI bus is a parallel data path that replaces or is provided in addition to an ISA bus. The system processor and memory can be attached directly to the PCI bus, for example. Other devices such as graphic display adapters, disk controllers, sound cards, etc. can also attach directly or indirectly (e.g., through a host bridge) to the PCI bus.
In a digital computer, a microprocessor operates on data stored in a main memory. Since there are practical size limitations on the main memory, bulk memory storage devices are provided in addition to and separately from the main memory. When the microprocessor wants to make use of data stored in bulk storage, for example, a hard disk, the data is moved from the hard disk into the main memory. This movement of blocks of memory inside the computer is a very time consuming process and would severely hamper the performance of the computer system if the microprocessor were to control the memory transfers itself.
In order to relieve the microprocessor from the chore of controlling the movement of blocks of memory inside the computer, a direct memory access (DMA) controller is normally used. The DMA controller receives descriptor information from the microprocessor as to the base location from where bytes are to be moved, the address to where these bytes should go, and the number of bytes to move. Once it has been programmed by the microprocessor, the DMA controller oversees the transfer of the memory data within the computer system. Normally, DMA operations are used to move data between input/output (I/O) devices and memory.
Some of the efficiency of the PCI bus is due to the feature that the devices connected to the PCI bus can become DMA masters, and are not just slaves. Further, the PCI bus is a bursting bus, so that a single DMA transfer of data may be performed with one starting address followed by a large block of data. This bursting is more efficient than transferring data in individual small pieces, since the bus does not have to be constantly re-acquired for each piece of data.
Performing DMA transfers of data on a PCI bus in a multi-channel system, in which multiple sources transfer data to and from a host system over separate channels, is difficult to do efficiently. This is because it is hard to continue to do block transfers of data when multiple channels of data are attempting to use the bus. Obtaining and re-obtaining the bus for each of the separate channels as data comes in over the multiple channels reduces the efficiency of the bus, mitigating a significant advantage of the PCI bus.
Another complication created by a multi-channel system is that buffers may be returned in a different order than they were obtained. This is due to the fact that the channels will not typically complete their transfers at the same rate, so it is possible that a first data buffer obtained for a transfer on a first channel may not be returned for re-use before a second data buffer that was subsequently obtained for a transfer on a second channel that has a faster source of data. This presents a management problem in that the currently available data buffers (or descriptors for the buffers) need to be readily identifiable. Since the buffers are often returned out of order in a multi-channel system, the descriptors in a descriptor queue are normally marked to indicate whether the descriptors are available. The descriptor queue must then be searched whenever a transfer is to be performed to find currently available descriptors. This management overhead adds to the inefficiency of transfers.